home *** CD-ROM | disk | FTP | other *** search
- /* OS- and machine-dependent stuff for SYS5 */
-
- /*
- FILE: UNIX.io.c
-
- Routines:
- ioinit()
- iostop()
- asy_init()
- asy_stop()
- asy_speed()
- asy_output()
- asy_recv()
- dir()
- Written or converted by Mikel Matthews, N9DVG
- SYS5 added by Jere Sandidge, K4FUM
- Directory pipe added by Ed DeHart, WA3YOA
- Numerous changes by Charles Hedrick and John Limpert, N3DMC
- Hell, *I* even hacked on it... :-) Bdale, N3EUA
-
- If you want to use the select code, define SELECT in the makefile or
- in this file.
- */
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <termio.h>
- #include <signal.h>
- #include <sys/file.h>
- #include <sys/dir.h>
- #include <time.h>
- #include <fcntl.h>
- #include "global.h"
- #include "asy.h"
- #include "mbuf.h"
- #include "internet.h"
- #include "iface.h"
- #include "unix.h"
- #include "cmdparse.h"
-
- #ifndef B19200
- #define B19200 EXTA
- #endif
-
- #ifndef B38400
- #define B38400 EXTB
- #endif
-
- struct asy asy[ASY_MAX];
- struct interface *ifaces;
- struct termio mysavetty, savecon;
- int savettyfl;
- int IORser[ASY_MAX];
- char *ttbuf;
- int slipisopen;
-
-
- /* Called at startup time to set up console I/O, memory heap */
- ioinit()
- {
- struct termio ttybuf;
- extern int iostop();
-
- (void) signal(SIGHUP, iostop);
- (void) signal(SIGINT, iostop);
- (void) signal(SIGQUIT, iostop);
- (void) signal(SIGTERM, iostop);
-
- ioctl(0, TCGETA, &ttybuf);
- savecon = ttybuf;
-
- ttybuf.c_iflag &= ~IXON;
- ttybuf.c_lflag &= ~(ICANON|ISIG|ECHO);
- ttybuf.c_cc[VTIME] = '\0';
- ttybuf.c_cc[VMIN] = '\01';
- if ((savettyfl = fcntl(0, F_GETFL, 0)) == -1) {
- perror("Could not read console flags");
- return -1;
- }
- fcntl(0, F_SETFL, savettyfl | O_NDELAY);
-
- ioctl(0, TCSETAW, &ttybuf);
- }
-
-
- /* Called just before exiting to restore console state */
- iostop()
- {
- setbuf(stdout,NULLCHAR);
-
- while (ifaces != NULLIF) {
- if (ifaces->stop != NULLFP)
- (*ifaces->stop)(ifaces->dev);
- ifaces = ifaces->next;
- }
-
- ioctl(0, TCSETAW, &savecon);
- fcntl(0, F_SETFL, savettyfl);
- exit(0);
- }
-
- /* Initialize asynch port "dev" */
- int
- asy_init(dev, arg1, arg2, bufsize)
- int16 dev;
- char *arg1, *arg2;
- unsigned bufsize;
- {
- register struct asy *ap;
- struct termio sgttyb;
-
- #ifdef SYS5_DEBUG
- printf("asy_init: called\n");
- #endif /* SYS5_DEBUG */
-
- if (dev >= nasy)
- return -1;
-
- ap = &asy[dev];
- ap->tty = malloc(strlen(arg2)+1);
- strcpy(ap->tty, arg2);
- printf("asy_init: tty name = %s\n", ap->tty);
-
- if ((IORser[dev] = open(ap->tty, (O_RDWR|O_NDELAY), 0)) < 0) {
- perror("Could not open device IORser");
- return -1;
- }
-
- /*
- * get the stty structure and save it
- */
-
- if (ioctl(IORser[dev], TCGETA, &mysavetty) < 0) {
- perror("ioctl failed on device");
- return -1;
- }
-
- /*
- * copy over the structure
- */
-
- sgttyb = mysavetty;
- sgttyb.c_iflag = (IGNBRK | IGNPAR);
- sgttyb.c_oflag = 0;
- sgttyb.c_lflag = 0;
- sgttyb.c_cflag = (B9600 | CS8 | CREAD);
- sgttyb.c_cc[VTIME] = 0;
- sgttyb.c_cc[VMIN] = 0;
-
- if (ioctl(IORser[dev], TCSETAF, &sgttyb) < 0) {
- perror("ioctl could not set parameters for IORser");
- return -1;
- }
-
- return 0;
- }
-
-
- int
- asy_stop(dev)
- int dev;
- {
- }
-
-
- /* Set asynch line speed */
- int
- asy_speed(dev, speed)
- int dev;
- int speed;
- {
- struct termio sgttyb;
-
- if (speed == 0 || dev >= nasy)
- return -1;
-
- #ifdef SYS5_DEBUG
- printf("asy_speed: Setting speed for device %d to %d\n",dev, speed);
- #endif
-
- asy[dev].speed = speed;
-
- if (ioctl(IORser[dev], TCGETA, &sgttyb) < 0) {
- perror("ioctl could not set parameters");
- return -1;
- }
-
- sgttyb.c_cflag &= ~CBAUD;
-
- switch ((unsigned)speed) {
- case 0:
- sgttyb.c_cflag |= B0;
- break;
- case 50:
- sgttyb.c_cflag |= B50;
- break;
- case 75:
- sgttyb.c_cflag |= B75;
- break;
- case 110:
- sgttyb.c_cflag |= B110;
- break;
- case 134:
- sgttyb.c_cflag |= B134;
- break;
- case 150:
- sgttyb.c_cflag |= B150;
- break;
- case 200:
- sgttyb.c_cflag |= B200;
- break;
- case 300:
- sgttyb.c_cflag |= B300;
- break;
- case 600:
- sgttyb.c_cflag |= B600;
- break;
- case 1200:
- sgttyb.c_cflag |= B1200;
- break;
- case 1800:
- sgttyb.c_cflag |= B1800;
- break;
- case 2400:
- sgttyb.c_cflag |= B2400;
- break;
- case 4800:
- sgttyb.c_cflag |= B4800;
- break;
- case 9600:
- sgttyb.c_cflag |= B9600;
- break;
- case 19200:
- sgttyb.c_cflag |= B19200;
- break;
- case 38400:
- sgttyb.c_cflag |= B38400;
- break;
- default:
- printf("asy_speed: Unknown speed (%d)\n", speed);
- break;
- }
-
- #ifdef SYS5_DEBUG
- printf("speed = %d\n", sgttyb.sg_ispeed);
- #endif /* SYS5_DEBUG */
-
- if (ioctl(IORser[dev], TCSETAW, &sgttyb) < 0) {
- perror("ioctl could not set parameters for IORser");
- return -1;
- }
-
- return 0;
- }
-
-
- /* Send a buffer to serial transmitter */
- asy_output(dev, buf, cnt)
- unsigned dev;
- char *buf;
- unsigned short cnt;
- {
- #ifdef SYS5_DEBUG
- printf("asy_output called. dev = %d, cnt = %d\n", dev, cnt);
- printf("buf = %lx\n", (long) buf);
- fflush(stdout);
- #endif
-
- if (dev >= nasy)
- return -1;
-
- if (write(IORser[dev], buf, cnt) < cnt) {
- perror("asy_output");
- printf("asy_output: error in writing to device %d\n", dev);
- return -1;
- }
-
- return 0;
- }
-
- /* Receive characters from asynch line
- * Returns count of characters read
- */
- unsigned
- asy_recv(dev,buf,cnt)
- int dev;
- char *buf;
- unsigned cnt;
- {
- #define IOBUFLEN 256
- unsigned tot;
- int r;
- static struct {
- char buf[IOBUFLEN];
- char *data;
- int cnt;
- } IOBUF[ASY_MAX];
-
- #ifdef SELECT
- int mask;
- int writemask;
- int ok;
- struct timeval timeout;
- timeout.tv_sec = 0;
- timeout.tv_usec = 35;
- mask = (1<<IORser[dev]);
- writemask = (1<<IORser[dev]);
- ok = 0;
- tot = 0;
- ok = select(mask, &mask, 0, 0, &timeout);
- if ( mask & (1<<IORser[dev]))
- {
- tot = read(IORser[dev], buf, cnt);
- }
- return (tot);
- #else
- if(IORser[dev] < 0) {
- printf("asy_recv: bad file descriptor passed for device %d\n",
- dev);
- return(0);
- }
- tot = 0;
- /* fill the read ahead buffer */
- #ifdef notdef
- if(IOBUF[dev].cnt == 0 && (rdchk(IORser[dev]) > 0)) {
- #else
- if(IOBUF[dev].cnt == 0) {
- #endif
- IOBUF[dev].data = IOBUF[dev].buf;
- r = read(IORser[dev], IOBUF[dev].data, IOBUFLEN);
- /* check the read */
- if (r == -1) {
- IOBUF[dev].cnt = 0; /* bad read */
- perror("asy_recv");
- printf("asy_recv: error in reading from device %d\n", dev);
- return(0);
- } else
- IOBUF[dev].cnt = r;
- }
- r = 0; /* return count */
- /* fetch what you need with no system call overhead */
- if(IOBUF[dev].cnt > 0) {
- if(cnt == 1) { /* single byte copy, do it here */
- *buf = *IOBUF[dev].data++;
- IOBUF[dev].cnt--;
- r = 1;
- } else { /* multi-byte copy, left memcpy do the work */
- unsigned n = min(cnt, IOBUF[dev].cnt);
- memcpy(buf, IOBUF[dev].data, n);
- IOBUF[dev].cnt -= n;
- IOBUF[dev].data += n;
- r = n;
- }
- }
- tot = (unsigned int) r;
- return (tot);
- #endif
- }
-
- /* Generate a directory listing by opening a pipe to /bin/ls.
- * If full == 1, give a full listing; else return just a list of names.
- */
- FILE *
- dir(path,full)
- char *path;
- int full;
- {
- FILE *fp;
- char cmd[1024];
-
- if (path == NULLCHAR || path[0] == '\0')
- path = ".";
-
- #ifdef SYS5_DEBUG
- printf("DIR: path = %s\n", path);
- #endif /* SYS5_DEBUG */
-
- if (full)
- sprintf(cmd,"ls -l %s", path);
- else
- sprintf(cmd, "ls %s", path);
-
- if ((fp = popen(cmd,"r")) == NULLFILE) {
- perror("popen");
- return NULLFILE;
- }
-
- return fp;
- }
-
-
- asy_ioctl(interface, argc, argv)
- struct interface *interface;
- int argc;
- char *argv[];
- {
- if (argc < 1) {
- printf("%d\r\n", asy[interface->dev].speed);
- return 0;
- }
-
- return asy_speed(interface->dev, atoi(argv[0]));
- }
-
- int
- OpenPty()
- {
- extern int errno;
- struct termio ttybuf;
- int pty;
- int i, j;
- int tmaster;
- int letcnt=0, numcnt=0;
-
- static char *letters = "pqrs",
- *numbers = "0123456789abcdef";
- /*
- static char *letters = "p",
- *numbers = "012";
- */
- #ifdef hpux
- static char master[] = "/dev/ptym/ptyXX";
- #else
- static char master[] = "/dev/ptyXX";
- #endif
- static int letmax, nummax;
-
- letmax=strlen(letters)-1, nummax=strlen(numbers)-1;
- do {
- #ifdef hpux
- master[strlen("/dev/ptym/pty")] = letters[letcnt];
- master[strlen("/dev/ptym/ptyX")] = numbers[numcnt];
- #else
- master[strlen("/dev/pty")] = letters[letcnt];
- master[strlen("/dev/ptyX")] = numbers[numcnt];
- #endif
- if (letcnt > letmax) {
- return -1;
- } else if (++numcnt > nummax) {
- letcnt++;
- numcnt = 0;
- }
- } while ((pty=open(master, O_RDWR | O_NDELAY)) < 0);
-
- return(pty);
- }
-